home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 424_01 / ed_157 / copier.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-10  |  6.6 KB  |  263 lines

  1. /*
  2.  * Copyright (C) 1992 by Rush Record (rhr@clio.rice.edu)
  3.  * 
  4.  * This file is part of ED.
  5.  * 
  6.  * ED is free software; you can redistribute it and/or modify it under the terms
  7.  * of the GNU General Public License as published by the Free Software Foundation.
  8.  * 
  9.  * ED is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  10.  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  11.  * PARTICULAR PURPOSE.  See the GNU General Public License for more details.
  12.  * 
  13.  * You should have received a copy of the GNU General Public License along with ED
  14.  * (see the file COPYING).  If not, write to the Free Software Foundation, 675
  15.  * Mass Ave, Cambridge, MA 02139, USA.
  16.  */
  17. #include "opsys.h"
  18.  
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21.  
  22. #include "rec.h"
  23. #include "window.h"
  24. #include "ed_dec.h"
  25. #include "buffer.h"
  26.  
  27. /******************************************************************************\
  28. |Routine: copier
  29. |Callby: killer
  30. |Purpose: Handles copying of text from windows to buffer. Returns 1 if anything was
  31. |         actually copied, else 0.
  32. |Arguments:
  33. |    offset is the offset from the current position to the other end of the
  34. |            text to be deleted.
  35. |    buffer is the buffer into which the copied data is to be saved.
  36. |    append is a flag that causes the copied data to be appended to the buffer,
  37. |            instead of replacing it entirely.
  38. \******************************************************************************/
  39. Int copier(offset,buffer,append,boxmode)
  40. Int offset,append,boxmode;
  41. buf_ptr buffer;
  42. {
  43.     rec_ptr otherrec,mergerec;
  44.     register rec_ptr rec;
  45.     Int firstcol,lastcol,firstbyt,lastbyt,otherbyt,nrecs,modified_pos;
  46.     register Int i;
  47.  
  48.     modified_pos = 0;    /* flag that we had to move up from <end> before beginning the copy operation */
  49.     if(!offset)    /* if we are on the select range marker, and killing, handle specially */
  50.     {
  51.         if(append)    /* appending nothing does nothing */
  52.             return(1);
  53.         buffer_empty(buffer);    /* killing nothing only empties the buffer */
  54.         return(1);
  55.     }
  56.     else if(offset < 0)    /* we are deleting backwards from current position */
  57.     {
  58.         if(CURREC == BASE->next && !CURBYT)    /* ignore backward kills at top of file */
  59.         {
  60.             abort_key();
  61.             return(0);
  62.         }
  63. /* check for some pathological things */
  64.         if(boxmode)
  65.         {
  66.              if(CURREC == BASE)
  67.             {
  68.                 if(CURREC->next == BASE)    /* box cut in empty buffer does nothing except to paste buffer */
  69.                 {
  70.                     if(append)    /* appending nothing does nothing */
  71.                         return(1);
  72.                     buffer_empty(buffer);    /* killing nothing only empties the buffer */
  73.                     return(1);
  74.                 }
  75.                 WANTCOL = 1;
  76.                 up_arrow(1);    /* move up to start of last record in buffer */
  77.                 offset += CURREC->length + 1;    /* offset is less negative, by the length of the last record, plus 1 for the newline */
  78.                 modified_pos = 1;
  79.             }
  80.         }
  81. /* find the other end of the buffer, backwards */
  82.         otherrec = CURREC;
  83.         otherbyt = CURBYT;
  84.         nrecs = 1;
  85.         while(offset++ < 0)
  86.         {
  87.             if(!otherbyt)
  88.             {
  89.                 if(otherrec->prev == BASE)
  90.                 {
  91.                     abort_key();
  92.                     return(0);
  93.                 }
  94.                 otherrec = otherrec->prev;
  95.                 otherbyt = otherrec->length;
  96.                 nrecs++;
  97.             }
  98.             else
  99.                 otherbyt--;
  100.         }
  101. /* if box cut in effect, get column range */
  102.         if(boxmode)
  103.         {
  104.             firstcol = get_column(CURREC,CURBYT);
  105.             lastcol = get_column(otherrec,otherbyt);
  106.             if(firstcol > lastcol)
  107.             {
  108.                 i = firstcol;
  109.                 firstcol = lastcol;
  110.                 lastcol = i;
  111.             }
  112.         }
  113. /* save records to buffer */
  114.         if(!append)
  115.             buffer_empty(buffer);
  116.         else
  117.         {
  118.             if(buffer->first == (rec_ptr)&buffer->first)    /* if the buffer is empty, forget about appending */
  119.                 append = 0;
  120.             else
  121.                 mergerec = buffer->last;
  122.         }
  123.         if(boxmode)
  124.         {
  125.             for(rec = otherrec;rec != CURREC->next;rec = rec->next)
  126.             {
  127.                 firstbyt = get_colbyt(rec,firstcol);    /* get_colbyt must convert tabs to spaces, make record long enough, etc. */
  128.                 lastbyt = get_colbyt(rec,lastcol);
  129.                 buffer_append(buffer,rec,firstbyt,lastbyt + 1);
  130.             }
  131.             if(append)
  132.                 buffer->nrecs += nrecs;
  133.             else
  134.                 buffer->nrecs = nrecs;
  135.         }
  136.         else
  137.         {
  138.             if(otherrec == CURREC)
  139.                 buffer_append(buffer,CURREC,otherbyt,CURBYT);
  140.             else
  141.             {
  142.                 rec = otherrec;
  143.                 buffer_append(buffer,rec,otherbyt,rec->length);
  144.                 rec = rec->next;
  145.                 for(i = 1;i < nrecs - 1;i++)
  146.                 {
  147.                     buffer_append(buffer,rec,0,rec->length);
  148.                     rec = rec->next;
  149.                 }
  150.                 buffer_append(buffer,rec,0,CURBYT);
  151.             }
  152.             if(!append)
  153.                 buffer->nrecs = nrecs;
  154.             else
  155.             {
  156.                 buffer->nrecs += nrecs - 1;
  157.                 rec_merge(&mergerec);
  158.             }
  159.         }
  160.         buffer->direction = -1;
  161.     }
  162.     else    /* we are deleting forwards from the current position */
  163.     {
  164.         if(CURREC == BASE)    /* ignore forward kills at end of file */
  165.         {
  166.             abort_key();
  167.             return(0);
  168.         }
  169. /* find the other end of the buffer, forwards */
  170.         otherrec = CURREC;
  171.         otherbyt = CURBYT;
  172.         nrecs = 1;
  173.         while(offset-- > 0)
  174.         {
  175.             if(otherrec == BASE)
  176.             {
  177.                 abort_key();
  178.                 return(0);
  179.             }
  180.             if(otherbyt == otherrec->length)
  181.             {
  182.                 otherrec = otherrec->next;
  183.                 otherbyt = 0;
  184.                 nrecs++;
  185.             }
  186.             else
  187.                 otherbyt++;
  188.         }
  189. /* check for some pathological things */
  190.         if(boxmode)
  191.         {
  192.              if(otherrec == BASE)
  193.             {
  194.                 otherrec = otherrec->prev;
  195.                 otherbyt = 0;
  196.                 nrecs--;
  197.                 offset -= otherrec->length + 1;    /* offset is smaller, by the length of the last record, plus 1 for the newline */
  198.             }
  199. /* if box cut in effect, get column range */
  200.             firstcol = get_column(CURREC,CURBYT);
  201.             lastcol = get_column(otherrec,otherbyt);
  202.             if(firstcol > lastcol)
  203.             {
  204.                 i = firstcol;
  205.                 firstcol = lastcol;
  206.                 lastcol = i;
  207.             }
  208.         }
  209. /* save records to buffer */
  210.         if(!append)
  211.             buffer_empty(buffer);
  212.         else
  213.         {
  214.             if(buffer->first == (rec_ptr)&buffer->first)    /* if the buffer is empty, forget about appending */
  215.                 append = 0;
  216.             else
  217.                 mergerec = buffer->last;
  218.         }
  219.         if(boxmode)
  220.         {
  221.             for(rec = CURREC;rec != otherrec->next;rec = rec->next)
  222.             {
  223.                 firstbyt = get_colbyt(rec,firstcol);    /* get_colbyt must convert tabs to spaces, make record long enough, etc. */
  224.                 lastbyt = get_colbyt(rec,lastcol);
  225.                 buffer_append(buffer,rec,firstbyt,lastbyt + 1);
  226.             }
  227.             if(append)
  228.                 buffer->nrecs += nrecs;
  229.             else
  230.                 buffer->nrecs = nrecs;
  231.         }
  232.         else
  233.         {
  234.             if(otherrec == CURREC)
  235.                 buffer_append(buffer,CURREC,CURBYT,otherbyt);
  236.             else
  237.             {
  238.                 buffer_append(buffer,CURREC,CURBYT,CURREC->length);
  239.                 rec = CURREC->next;
  240.                 for(i = 1;i < nrecs - 1;i++)
  241.                 {
  242.                     buffer_append(buffer,rec,0,rec->length);
  243.                     rec = rec->next;
  244.                 }
  245.                 buffer_append(buffer,rec,0,otherbyt);
  246.             }
  247.             if(!append)
  248.                 buffer->nrecs = nrecs;
  249.             else
  250.             {
  251.                 buffer->nrecs += nrecs - 1;
  252.                 rec_merge(&mergerec);
  253.             }
  254.         }
  255.         buffer->direction = 1;
  256.     }
  257.     CURBYT = get_colbyt(CURREC,CURCOL);
  258.     if(modified_pos)
  259.         down_arrow(1);
  260.     return(1);
  261. }
  262.  
  263.